<?php

namespace Illuminate\Auth;

use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Traits\Macroable;

/**
 * 基于请求的身份认证守卫
 */
class RequestGuard implements Guard
{
    use GuardHelpers, Macroable;

    /**
     * 守卫回调函数
     *
     * @var callable
     */
    protected $callback;

    /**
     * 当前请求对象
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * 创建一个新的身份认证守卫
     *
     * @param  callable $callback 回调函数
     * @param  \Illuminate\Http\Request $request 请求对象
     * @param  \Illuminate\Contracts\Auth\UserProvider|null $provider 用户提供者
     * @return void
     */
    public function __construct(callable $callback, Request $request, UserProvider $provider = null)
    {
        $this->request = $request;
        $this->callback = $callback;
        $this->provider = $provider;
    }

    /**
     * Get the currently authenticated user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user()
    {
        // 如果我们已经对当前请求检索了用户，我们可以立即返回它。
        if (!is_null($this->user)) {
            return $this->user;
        }

        return $this->user = call_user_func(
            $this->callback, $this->request, $this->getProvider()
        );
    }

    /**
     * 验证用户的凭证数据
     *
     * @param  array $credentials
     * @return bool
     */
    public function validate(array $credentials = [])
    {
        return !is_null((new static(
            $this->callback, $credentials['request'], $this->getProvider()
        ))->user());
    }

    /**
     * 设置当前请求对象
     *
     * @param  \Illuminate\Http\Request $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }
}
